import { ethers } from "ethers";
import { get, writable } from 'svelte/store';


const target_network = {
    name: "homestead",
    chainId: 1
};
// const target_network = {
//     name: "unknown",
//     chainId: 1337
// };
// const target_network = {
//     name: "ropsten",
//     chainId: 3
// };

let walletChangeCallbacks = [];
export function onWalletChange(callback) {
    walletChangeCallbacks.push(callback);
}
async function walletChanged() {
    for (let i = 0; i < walletChangeCallbacks.length; i++) {
        await walletChangeCallbacks[i](get(correct_network));
    }
}
export const target_mainnet = target_network.chainId === 1;


export let unlocked = writable(false);
export let address = writable(null);
export let ENS = writable(null);

export let provider = null;
export let signer = null;
export let correct_network = writable(true);
export let wallet_injected = writable(true);

async function check_network(provider) {
    let network = await provider.getNetwork();
    correct_network.set(network.chainId === target_network.chainId);
}

async function recheck_wallet() {
    await check_network(provider);

    let _signer = provider.getSigner();
    let _address = await _signer.getAddress();
    if (_address !== get(address)) {
        address.set(_address);
        let _ens = await provider.lookupAddress(_address)
        ENS.set(_ens);

        await walletChanged();
    }

    setTimeout(recheck_wallet, 1000);
}


export let unlock_requested = writable(false);
function request_unlock() {
    unlock_requested.set(true);
    setTimeout(() => {
        unlock_requested.set(false);
    }, 5000);
}

function check_unlock() {
    setTimeout(async () => {

        try {
            const _provider = await new ethers.providers.Web3Provider(window.ethereum, "any");
            const _signer = _provider.getSigner();
            const connected_address = await _signer.getAddress();
            console.log("Wallet connected");
            do_unlock();
        } catch (e) {
            check_unlock();
        }
    }, 1000
    );
}


async function do_unlock() {
    unlocked.set(true);
    const _provider = await new ethers.providers.Web3Provider(window.ethereum, "any");
    provider = _provider;

    const _signer = _provider.getSigner();
    signer = _signer;

    await check_network(provider);

    provider.on("network", async (newNetwork, oldNetwork) => {
        await check_network(provider);
        await walletChanged();
    });

    address.set(await _signer.getAddress());

    unlockCallback();

    recheck_wallet();
}

export async function unlock() {
    try {
        request_unlock();
        await window.ethereum.request({
            method: 'eth_requestAccounts'
        });

    } catch (e) {
        console.log('Wallet request failed');
        console.log(e);
        if (e.code !== 4001) alert(e.message);
    }

    check_unlock();
}
export default async function init() {
    if (typeof window.ethereum === "undefined") {
        wallet_injected.set(false);
        console.log('not injected!');
        return;
    }
    window.ethereum.autoRefreshOnNetworkChange = false;
}

let unlockCallback = () => { };
export function onUnlocked(callback) {
    unlockCallback = callback;
}

init();
